#include <wx/wx.h>
#include "panel_chorus.h"
#include "MyCommon.h"
#include "DataSave.h"

#define SLI_MAX(max,min,step) (int)((max - min) / step)

wxDEFINE_EVENT(myEVT_CHORUS, MyEventChorus);
wxDEFINE_EVENT(myEVT_CHORUS_DRY, MyEventChorus);
wxDEFINE_EVENT(myEVT_CHORUS_WET, MyEventChorus);
wxDEFINE_EVENT(myEVT_CHORUS_PITCH, MyEventChorus);
wxDEFINE_EVENT(myEVT_CHORUS_RATE, MyEventChorus);
wxDEFINE_EVENT(myEVT_CHORUS_TONE, MyEventChorus);
wxDEFINE_EVENT(myEVT_CHORUS_ENABLE, MyEventChorus);


// wxBEGIN_EVENT_TABLE(PanelChorus, wxPanel)
//     EVT_SLIDER(PanelChorus::ID_SLI_DRY, PanelChorus::OnSliderChange)
//     EVT_SLIDER(PanelChorus::ID_SLI_WET, PanelChorus::OnSliderChange)
//     EVT_SLIDER(PanelChorus::ID_SLI_PITCH, PanelChorus::OnSliderChange)
//     EVT_SLIDER(PanelChorus::ID_SLI_RATE, PanelChorus::OnSliderChange)
//     EVT_SLIDER(PanelChorus::ID_SLI_TONE, PanelChorus::OnSliderChange)
//     EVT_TEXT_ENTER(PanelChorus::ID_TXT_DRY,PanelChorus::OnTextEnter)
//     EVT_TEXT_ENTER(PanelChorus::ID_TXT_WET,PanelChorus::OnTextEnter)
//     EVT_TEXT_ENTER(PanelChorus::ID_TXT_PITCH,PanelChorus::OnTextEnter)
//     EVT_TEXT_ENTER(PanelChorus::ID_TXT_RATE,PanelChorus::OnTextEnter)
//     EVT_TEXT_ENTER(PanelChorus::ID_TXT_TONE,PanelChorus::OnTextEnter)
//     EVT_CHECKBOX(PanelChorus::ID_CHK_SWITCH,PanelChorus::OnChkChange)
// wxEND_EVENT_TABLE()


PanelChorus::PanelChorus(const wxString &title, wxXmlNode *node, wxWindowID id, wxWindow *parent)
    : wxPanel(parent,id,wxDefaultPosition,wxDefaultSize,wxTAB_TRAVERSAL)
{
    this_id = id;
    SetSize(200, 300);

    root_node = node;
    select_index = 0;

    wxWindowID cid = id+1;

    ID_TXT_DRY = cid++;
    ID_TXT_WET = cid++;
    ID_TXT_PITCH = cid++;;
    ID_TXT_RATE = cid++;;
    ID_TXT_TONE = cid++;;
    ID_SLI_DRY = cid++;
    ID_SLI_WET = cid++;
    ID_SLI_PITCH = cid++;;
    ID_SLI_RATE = cid++;;
    ID_SLI_TONE = cid++;;
    ID_CHK_SWITCH = cid++;;
    ID_CHO_PRESET = cid ++;

    wxCheckBox      *chk_enable  = new wxCheckBox(this  , ID_CHK_SWITCH, "Enable");
    wxTextCtrl      *txt_dry     = new wxTextCtrl(this  , ID_TXT_DRY   , mDoubleToString(dry_min)  , wxDefaultPosition, wxDefaultSize    , wxTE_PROCESS_ENTER);
    wxTextCtrl      *txt_wet     = new wxTextCtrl(this  , ID_TXT_WET   , mDoubleToString(wet_min)  , wxDefaultPosition, wxDefaultSize    , wxTE_PROCESS_ENTER);
    wxTextCtrl      *txt_pitch   = new wxTextCtrl(this  , ID_TXT_PITCH , mDoubleToString(pitch_min), wxDefaultPosition, wxDefaultSize    , wxTE_PROCESS_ENTER);
    wxTextCtrl      *txt_rate    = new wxTextCtrl(this  , ID_TXT_RATE  , mDoubleToString(rate_min) , wxDefaultPosition, wxDefaultSize    , wxTE_PROCESS_ENTER);
    wxTextCtrl      *txt_tone    = new wxTextCtrl(this  , ID_TXT_TONE  , mDoubleToString(tone_min) , wxDefaultPosition, wxDefaultSize    , wxTE_PROCESS_ENTER);
    wxStaticText    *lab_dry     = new wxStaticText(this, wxID_ANY     , "Dry:");
    wxStaticText    *lab_wet     = new wxStaticText(this, wxID_ANY     , "Wet:");
    wxStaticText    *lab_pitch   = new wxStaticText(this, wxID_ANY     , "Pitch:");
    wxStaticText    *lab_rate    = new wxStaticText(this, wxID_ANY     , "Rate:");
    wxStaticText    *lab_tone    = new wxStaticText(this, wxID_ANY     , "Tone:");
    wxStaticText    *lab_preset  = new wxStaticText(this, wxID_ANY     , "Preset:");
    wxSlider        *sli_dry     = new wxSlider(this    , ID_SLI_DRY   , 0                         , 0                , SLI_MAX(dry_max  , dry_min             , dry_step));
    wxSlider        *sli_wet     = new wxSlider(this    , ID_SLI_WET   , 0                         , 0                , SLI_MAX(wet_max  , wet_min             , wet_step));
    wxSlider        *sli_pitch   = new wxSlider(this    , ID_SLI_PITCH , 0                         , 0                , SLI_MAX(pitch_max, pitch_min           , pitch_step));
    wxSlider        *sli_rate    = new wxSlider(this    , ID_SLI_RATE  , 0                         , 0                , SLI_MAX(rate_max , rate_min            , rate_step));
    wxSlider        *sli_tone    = new wxSlider(this    , ID_SLI_TONE  , 0                         , 0                , SLI_MAX(tone_max , tone_min            , rate_step));
    wxFlexGridSizer *layout_main = new wxFlexGridSizer(7, 3            , wxSize(3                  , 3));
    wxChoice        *cho_preset      = new wxChoice(this,     ID_CHO_PRESET);

    sli_dry->SetMinSize(wxSize(100, -1));
    sli_dry->SetTick(1);
    sli_wet->SetMinSize(wxSize(100, -1));
    sli_pitch->SetMinSize(wxSize(100, -1));
    sli_rate->SetMinSize(wxSize(100, -1));
    txt_dry->SetMinSize(wxSize(50, -1));
    txt_dry->SetMaxSize(wxSize(100, -1));
    txt_wet->SetMinSize(wxSize(50, -1));
    txt_wet->SetMaxSize(wxSize(100, -1));
    txt_pitch->SetMinSize(wxSize(50, -1));
    txt_pitch->SetMaxSize(wxSize(100, -1));
    txt_rate->SetMinSize(wxSize(50, -1));
    txt_rate->SetMaxSize(wxSize(100, -1));
    txt_tone->SetMinSize(wxSize(50, -1));
    txt_tone->SetMaxSize(wxSize(100, -1));

    sli_dry->Bind(wxEVT_SLIDER, &PanelChorus::OnSliderChange, this, ID_SLI_DRY);
    sli_wet->Bind(wxEVT_SLIDER, &PanelChorus::OnSliderChange, this, ID_SLI_WET);
    sli_pitch->Bind(wxEVT_SLIDER, &PanelChorus::OnSliderChange, this, ID_SLI_PITCH);
    sli_rate->Bind(wxEVT_SLIDER, &PanelChorus::OnSliderChange, this, ID_SLI_RATE);
    sli_tone->Bind(wxEVT_SLIDER, &PanelChorus::OnSliderChange, this, ID_SLI_TONE);
    txt_dry->Bind(wxEVT_TEXT_ENTER, &PanelChorus::OnTextEnter, this, ID_TXT_DRY);
    txt_wet->Bind(wxEVT_TEXT_ENTER, &PanelChorus::OnTextEnter, this, ID_TXT_WET);
    txt_pitch->Bind(wxEVT_TEXT_ENTER, &PanelChorus::OnTextEnter, this, ID_TXT_PITCH);
    txt_rate->Bind(wxEVT_TEXT_ENTER, &PanelChorus::OnTextEnter, this, ID_TXT_RATE);
    txt_tone->Bind(wxEVT_TEXT_ENTER, &PanelChorus::OnTextEnter, this, ID_TXT_TONE);
    chk_enable->Bind(wxEVT_CHECKBOX, &PanelChorus::OnChkChange, this, ID_CHK_SWITCH);
    cho_preset->Bind(wxEVT_CHOICE,        &PanelChorus::OnCombChange,   this, ID_CHO_PRESET);

    // cho_preset->Append("chorus-1");
    // cho_preset->Append("chorus-2");
    // cho_preset->Append("chorus-3");
    // cho_preset->Append("chorus-4");
    // cho_preset->Append("chorus-5");
    // cho_preset->Append("chorus-6");
    // cho_preset->Select(select_index);

    layout_main->Add(chk_enable  ,0,wxALIGN_CENTER_VERTICAL | wxEXPAND);
    layout_main->AddStretchSpacer();
    layout_main->AddStretchSpacer();
    layout_main->Add(lab_dry     ,0,wxALIGN_CENTER_VERTICAL | wxEXPAND);
    layout_main->Add(txt_dry     ,0,wxALIGN_CENTER_VERTICAL | wxEXPAND);
    layout_main->Add(sli_dry     ,0,wxALIGN_CENTER_VERTICAL | wxEXPAND);
    layout_main->Add(lab_wet     ,0,wxALIGN_CENTER_VERTICAL | wxEXPAND);
    layout_main->Add(txt_wet     ,0,wxALIGN_CENTER_VERTICAL | wxEXPAND);
    layout_main->Add(sli_wet     ,0,wxALIGN_CENTER_VERTICAL | wxEXPAND);
    layout_main->Add(lab_pitch,0,wxALIGN_CENTER_VERTICAL | wxEXPAND);
    layout_main->Add(txt_pitch,0,wxALIGN_CENTER_VERTICAL | wxEXPAND);
    layout_main->Add(sli_pitch,0,wxALIGN_CENTER_VERTICAL | wxEXPAND);
    layout_main->Add(lab_rate    ,0,wxALIGN_CENTER_VERTICAL | wxEXPAND);
    layout_main->Add(txt_rate    ,0,wxALIGN_CENTER_VERTICAL | wxEXPAND);
    layout_main->Add(sli_rate    ,0,wxALIGN_CENTER_VERTICAL | wxEXPAND);
    layout_main->Add(lab_tone    ,0,wxALIGN_CENTER_VERTICAL | wxEXPAND);
    layout_main->Add(txt_tone    ,0,wxALIGN_CENTER_VERTICAL | wxEXPAND);
    layout_main->Add(sli_tone    ,0,wxALIGN_CENTER_VERTICAL | wxEXPAND);
    layout_main->Add(lab_preset,0,wxALIGN_CENTER_VERTICAL | wxEXPAND);
    layout_main->Add(cho_preset,0,wxALIGN_CENTER_VERTICAL | wxEXPAND);
    layout_main->AddStretchSpacer();
    layout_main->AddGrowableCol(0,0);
    layout_main->AddGrowableCol(1,0);
    layout_main->AddGrowableCol(2,1);

    SetSizer(layout_main);

    paneInfo.Caption(title);
    paneInfo.Dock();
    paneInfo.Dockable(true);
    paneInfo.CloseButton(true);
    paneInfo.MaximizeButton(true);
    paneInfo.MinimizeButton(true);
    paneInfo.DestroyOnClose(false);
    // paneInfo.Direction(wxLeft);

    param_event.SetEventObject(this);
    // param.dry = dry_min;
    // param.wet = wet_min;
    // param.pitch = pitch_min;
    // param.rate = rate_min;
    // param.tone = tone_min;
    // param.enable = false;

    // param_event.SetDry(param.dry);
    // param_event.SetWet(param.wet);
    // param_event.SetPitch(param.pitch);
    // param_event.SetRate(param.rate);
    // param_event.SetTone(param.tone);
    // param_event.SetEnable(param.enable);

    param.dry = dry_min;
    param.wet = wet_min;
    param.pitch = pitch_min;
    param.rate = rate_min;
    param.tone = tone_min;
    param.enable = false;

    // wxString str;
    // wxString select_name = attr_name_preset_default;
    // if(DataSave::NodeAttributesGetValue(root_node,attr_name_select,str))
    // {
    //     select_name = str;
    // }
    // else
    // {
    //     DataSave::NodeAttributesSetValue(root_node,attr_name_select,attr_name_preset_default);
    // }
    preset_node = nullptr;
    if(cho_preset->GetCount() > 0)
    {
        preset_node = SelectPreset(cho_preset->GetString(select_index));
    }
}


wxAuiPaneInfo &PanelChorus::GetPaneInfo()
{
    return paneInfo;
}


void PanelChorus::SetShow(bool show)
{
    Show(show);
}


void PanelChorus::OnSliderChange(wxCommandEvent& event)
{
    int id = event.GetId();
    // switch(id)
    {
        if(id == ID_SLI_DRY)
        {
            wxSlider *sli = wxDynamicCast(FindWindowById(ID_SLI_DRY),wxSlider);
            wxTextCtrl *txt = wxDynamicCast(FindWindowById(ID_TXT_DRY),wxTextCtrl);
            double sv = sli->GetValue();
            double v = dry_min + sv / (1/dry_step);
            txt->SetValue(mDoubleToString(v));
            param.dry = v;
            TrigerEvent(EV_DRY);
        }
        else if(id == ID_SLI_WET)
        {
            wxSlider *sli = wxDynamicCast(FindWindowById(ID_SLI_WET),wxSlider);
            wxTextCtrl *txt = wxDynamicCast(FindWindowById(ID_TXT_WET),wxTextCtrl);
            double sv = sli->GetValue();
            double v = wet_min + sv / (1/wet_step);
            txt->SetValue(mDoubleToString(v));
            param.wet = v;
            TrigerEvent(EV_WET);
        }
        else if(id == ID_SLI_RATE)
        {
            wxSlider *sli = wxDynamicCast(FindWindowById(ID_SLI_RATE),wxSlider);
            wxTextCtrl *txt = wxDynamicCast(FindWindowById(ID_TXT_RATE),wxTextCtrl);
            double sv = sli->GetValue();
            double v = rate_min + sv / (1/rate_step);
            txt->SetValue(mDoubleToString(v));
            param.rate = v;
            TrigerEvent(EV_RATE);
        }
        else if(id == ID_SLI_PITCH)
        {
            wxSlider *sli = wxDynamicCast(FindWindowById(ID_SLI_PITCH),wxSlider);
            wxTextCtrl *txt = wxDynamicCast(FindWindowById(ID_TXT_PITCH),wxTextCtrl);
            double sv = sli->GetValue();
            double v = pitch_min + sv / (1/pitch_step);
            txt->SetValue(mDoubleToString(v));
            param.pitch = v;
            TrigerEvent(EV_PITCH);
        }
        else if(id == ID_SLI_TONE)
        {
            wxSlider *sli = wxDynamicCast(FindWindowById(ID_SLI_TONE),wxSlider);
            wxTextCtrl *txt = wxDynamicCast(FindWindowById(ID_TXT_TONE),wxTextCtrl);
            double sv = sli->GetValue();
            double v = tone_min + sv / (1/tone_step);
            txt->SetValue(mDoubleToString(v));
            param.tone = v;
            TrigerEvent(EV_TONE);
        }
    }
}

void PanelChorus::OnTextEnter(wxCommandEvent& event)
{
    int type = event.GetEventType();
    int id = event.GetId();
    if(type == wxEVT_TEXT_ENTER)
    {
        if(id == ID_TXT_DRY)
        {
            wxTextCtrl *txt = wxDynamicCast(FindWindowById(ID_TXT_DRY),wxTextCtrl);
            double v ;
            if(txt->GetValue().ToDouble(&v) == true)
            {
                if((v >= dry_min) && (v <= dry_max))
                {
                    param.dry = v;
                }
            }
            double sv = (param.dry - dry_min) * (1/dry_step);
            wxSlider *sli = wxDynamicCast(FindWindowById(ID_SLI_DRY),wxSlider);
            sli->SetValue(sv);
            TrigerEvent(EV_DRY);
        }
        else if(id == ID_TXT_WET)
        {
            wxTextCtrl *txt = wxDynamicCast(FindWindowById(ID_TXT_WET),wxTextCtrl);
            double v ;
            if(txt->GetValue().ToDouble(&v) == true)
            {
                if((v >= wet_min) && (v <= wet_max))
                {
                    param.wet = v;
                }
            }
            double sv = (param.wet - wet_min) * (1/wet_step);
            wxSlider *sli = wxDynamicCast(FindWindowById(ID_SLI_WET),wxSlider);
            sli->SetValue(sv);
            TrigerEvent(EV_WET);
        }
        else if(id == ID_TXT_RATE)
        {
            wxTextCtrl *txt = wxDynamicCast(FindWindowById(ID_TXT_RATE),wxTextCtrl);
            double v ;
            if(txt->GetValue().ToDouble(&v) == true)
            {
                if((v >= rate_min) && (v <= rate_max))
                {
                    param.rate = v;
                }
            }
            double sv = (param.rate - rate_min) * (1/rate_step);
            wxSlider *sli = wxDynamicCast(FindWindowById(ID_SLI_RATE),wxSlider);
            sli->SetValue(sv);
            TrigerEvent(EV_RATE);
        }
        else if(id == ID_TXT_PITCH)
        {
            wxTextCtrl *txt = wxDynamicCast(FindWindowById(ID_TXT_PITCH),wxTextCtrl);
            double v ;
            if(txt->GetValue().ToDouble(&v) == true)
            {
                if((v >= pitch_min) && (v <= pitch_max))
                {
                    param.pitch = v;
                }
            }
            double sv = (param.pitch - pitch_min) * (1/pitch_step);
            wxSlider *sli = wxDynamicCast(FindWindowById(ID_SLI_PITCH),wxSlider);
            sli->SetValue(sv);
            TrigerEvent(EV_PITCH);
        }
        else if(id == ID_TXT_TONE)
        {
            wxTextCtrl *txt = wxDynamicCast(FindWindowById(ID_TXT_TONE),wxTextCtrl);
            double v ;
            if(txt->GetValue().ToDouble(&v) == true)
            {
                if((v >= tone_min) && (v <= tone_max))
                {
                    param.tone = v;
                }
            }
            double sv = (param.tone - tone_min) * (1/tone_step);
            wxSlider *sli = wxDynamicCast(FindWindowById(ID_SLI_TONE),wxSlider);
            sli->SetValue(sv);
            TrigerEvent(EV_TONE);
        }
    }
}

void PanelChorus::OnChkChange(wxCommandEvent &event)
{
    int id = event.GetId();
    if(id == ID_CHK_SWITCH)
    {
        wxCheckBox *chk = wxDynamicCast(FindWindowById(ID_CHK_SWITCH),wxCheckBox);
        param.enable = chk->IsChecked();
        TrigerEvent(EV_ENABLE);
    }
}


void PanelChorus::OnCombChange(wxCommandEvent& event)
{
    wxChoice *cmb = wxDynamicCast(FindWindowById(ID_CHO_PRESET),wxChoice);
    int i = cmb->GetSelection();
    if((unsigned int)i < cmb->GetCount())
    {
        select_index = i;
        preset_node = SelectPreset(cmb->GetString(i));
        param_event.SetPresetIndex(select_index);
        param_event.SetEventType(myEVT_CHORUS);
        ProcessWindowEvent(param_event);
    }
}

double PanelChorus::SetParamDry(double v)
{
    if(v < dry_min)
    {
        v = dry_min;
    }
    else if(v > dry_max)
    {
        v = dry_max;
    }
    double sv = (v - dry_min) * (1/dry_step);
    wxSlider *sli = wxDynamicCast(FindWindowById(ID_SLI_DRY),wxSlider);
    sli->SetValue(sv);
    wxTextCtrl *txt = wxDynamicCast(FindWindowById(ID_TXT_DRY),wxTextCtrl);
    txt->SetValue(mDoubleToString(v));
    param.dry = v;
    param_event.SetDry(v);
    return v;
}

double PanelChorus::SetParamWet(double v)
{
    if(v < wet_min)
    {
        v = wet_min;
    }
    else if(v > wet_max)
    {
        v = wet_max;
    }
    double sv = (v - wet_min) * (1/wet_step);
    wxSlider *sli = wxDynamicCast(FindWindowById(ID_SLI_WET),wxSlider);
    sli->SetValue(sv);
    wxTextCtrl *txt = wxDynamicCast(FindWindowById(ID_TXT_WET),wxTextCtrl);
    txt->SetValue(mDoubleToString(v));
    param.wet = v;
    param_event.SetWet(v);
    return v;
}

double PanelChorus::SetParamRate(double v)
{
    if(v < rate_min)
    {
        v = rate_min;
    }
    else if(v > rate_max)
    {
        v = rate_max;
    }
    double sv = (v - rate_min) * (1/rate_step);
    wxSlider *sli = wxDynamicCast(FindWindowById(ID_SLI_RATE),wxSlider);
    sli->SetValue(sv);
    wxTextCtrl *txt = wxDynamicCast(FindWindowById(ID_TXT_RATE),wxTextCtrl);
    txt->SetValue(mDoubleToString(v));
    param.rate = v;
    param_event.SetRate(v);
    return v;
}

double PanelChorus::SetParamPitch(double v)
{
    if(v < pitch_min)
    {
        v = pitch_min;
    }
    else if(v > pitch_max)
    {
        v = pitch_max;
    }
    double sv = (v - pitch_min) * (1/pitch_step);
    wxSlider *sli = wxDynamicCast(FindWindowById(ID_SLI_PITCH),wxSlider);
    sli->SetValue(sv);
    wxTextCtrl *txt = wxDynamicCast(FindWindowById(ID_TXT_PITCH),wxTextCtrl);
    txt->SetValue(mDoubleToString(v));
    param.pitch = v;
    param_event.SetPitch(v);
    return v;
}

double PanelChorus::SetParamTone(double v)
{
    if(v < tone_min)
    {
        v = tone_min;
    }
    else if(v > tone_max)
    {
        v = tone_max;
    }
    double sv = (v - tone_min) * (1/tone_step);
    wxSlider *sli = wxDynamicCast(FindWindowById(ID_SLI_TONE),wxSlider);
    sli->SetValue(sv);
    wxTextCtrl *txt = wxDynamicCast(FindWindowById(ID_TXT_TONE),wxTextCtrl);
    txt->SetValue(mDoubleToString(v));
    param.tone = v;
    param_event.SetTone(v);
    return v;
}

bool PanelChorus::SetParamEnable(bool v)
{
    wxCheckBox *chk = wxDynamicCast(FindWindowById(ID_CHK_SWITCH),wxCheckBox);
    chk->SetValue(v);
    param.enable = v;
    param_event.SetEnable(v);
    return v;
}

double PanelChorus::GetParamDry() { return param.dry; }
double PanelChorus::GetParamWet() { return param.wet; }
double PanelChorus::GetParamPitch() { return param.pitch; }
double PanelChorus::GetParamRate() { return param.rate; }
double PanelChorus::GetParamTone() { return param.tone; }
bool PanelChorus::GetParamEnable() { return param.enable; }

void PanelChorus::SetPresetIndex(const unsigned int index)
{
    wxChoice *cmb = wxDynamicCast(FindWindowById(ID_CHO_PRESET),wxChoice);
    if(index < cmb->GetCount())
    {
        select_index = index;
        param_event.SetPresetIndex(select_index);
        cmb->SetSelection(index);
        preset_node = SelectPreset(cmb->GetString(index));
    }
}

int PanelChorus::GetPresetIndex()
{
    return select_index;
}

void PanelChorus::TrigerEvent(int ev)
{
    switch(ev)
    {
        case EV_DRY:
        {
            param_event.SetEventType(myEVT_CHORUS_DRY);
            param_event.SetDry(param.dry);
            ProcessWindowEvent(param_event);
            DataSave::NodeAttributesSetValue(preset_node, attr_name_param_dry, mDoubleToString(param.dry).c_str(), true);
        }
        break;
        case EV_WET:
        {
            param_event.SetEventType(myEVT_CHORUS_WET);
            param_event.SetWet(param.wet);
            ProcessWindowEvent(param_event);
            DataSave::NodeAttributesSetValue(preset_node, attr_name_param_wet, mDoubleToString(param.wet).c_str(), true);
        }
        break;
        case EV_RATE:
        {
            param_event.SetEventType(myEVT_CHORUS_RATE);
            param_event.SetRate(param.rate);
            ProcessWindowEvent(param_event);
            DataSave::NodeAttributesSetValue(preset_node, attr_name_param_rate, mDoubleToString(param.rate).c_str(), true);
        }
        break;
        case EV_PITCH:
        {
            param_event.SetEventType(myEVT_CHORUS_PITCH);
            param_event.SetPitch(param.pitch);
            ProcessWindowEvent(param_event);
            DataSave::NodeAttributesSetValue(preset_node, attr_name_param_pitch, mDoubleToString(param.pitch).c_str(), true);
        }
        break;
        case EV_TONE:
        {
            param_event.SetEventType(myEVT_CHORUS_TONE);
            param_event.SetTone(param.tone);
            ProcessWindowEvent(param_event);
            DataSave::NodeAttributesSetValue(preset_node, attr_name_param_tone, mDoubleToString(param.tone).c_str(), true);
        }
        break;
        case EV_ENABLE:
        {
            param_event.SetEventType(myEVT_CHORUS_ENABLE);
            param_event.SetEnable(param.enable);
            ProcessWindowEvent(param_event);
            DataSave::NodeAttributesSetValue(preset_node, attr_name_param_enable, param.enable ? "1" : "0");
        }
        break;
    }
}


wxXmlNode *PanelChorus::SelectPreset(wxString name)
{
    double dry = param.dry;
    double wet = param.wet;
    double pitch = param.pitch;
    double rate = param.rate;
    double tone = param.tone;
    bool enable = param.enable;

    wxString str;
    wxXmlNode *child;
    child = root_node->GetChildren();
    while(child)
    {
        if(strcmp(child->GetName().c_str(), name.c_str()) == 0)
        {
            break;
        }
        child = child->GetNext();
    }
    if(child)
    {
        if(DataSave::NodeAttributesGetValue(child,attr_name_param_enable,str))
        {
            int v ;
            if(str.ToInt(&v))
            {
                enable = v > 0 ? true : false;
            }
        }
        if(DataSave::NodeAttributesGetValue(child,attr_name_param_dry,str))
        {
            double v;
            if(str.ToDouble(&v))
            {
                dry = v;
            }
        }
        if(DataSave::NodeAttributesGetValue(child,attr_name_param_wet,str))
        {
            double v;
            if(str.ToDouble(&v))
            {
                wet = v;
            }
        }
        if(DataSave::NodeAttributesGetValue(child,attr_name_param_pitch,str))
        {
            double v;
            if(str.ToDouble(&v))
            {
                pitch = v;
            }
        }
        if(DataSave::NodeAttributesGetValue(child,attr_name_param_rate,str))
        {
            double v;
            if(str.ToDouble(&v))
            {
                rate = v;
            }
        }
        if(DataSave::NodeAttributesGetValue(child,attr_name_param_tone,str))
        {
            double v;
            if(str.ToDouble(&v))
            {
                tone = v;
            }
        }
        SetParamEnable(enable);
        SetParamDry(dry);
        SetParamWet(wet);
        SetParamPitch(pitch);
        SetParamRate(rate);
        SetParamTone(tone);

        // if(child == nullptr)
        // {
        //     child = new wxXmlNode(wxXML_ELEMENT_NODE,name);
        //     WriteToXML(child);
        //     root_node->AddChild(child);
        // }
    }
    return child;
}

void PanelChorus::PresetListClear(void)
{
    wxChoice *cmb = wxDynamicCast(FindWindowById(ID_CHO_PRESET),wxChoice);
    if(cmb)
    {
        cmb->Clear();
        preset_node = nullptr;
    }
}

void PanelChorus::AddPresetList(const wxString &preset_name)
{
    wxChoice *cmb = wxDynamicCast(FindWindowById(ID_CHO_PRESET),wxChoice);
    if(cmb)
    {
        cmb->Append(preset_name);
    }
}


wxXmlNode *PanelChorus::SaveCurrentParamsToNewPreset(wxXmlNode *root, const wxString &new_preset_name,int &is_same)
{
    wxXmlNode *child = nullptr;
    is_same = 0;
    if((root != nullptr) && (new_preset_name.empty() == false))
    {
        //查找有没有名字相同的预设
        child = root->GetChildren();
        while(child)
        {
            if(strcmp(child->GetName().c_str(), new_preset_name.c_str()) == 0)
            {
                is_same = 1;
                return nullptr;
            }
            child = child->GetNext();
        }
        child = new wxXmlNode(wxXML_ELEMENT_NODE,new_preset_name);
        WriteToXML(child);
        root->AddChild(child);
        wxChoice *cmb = wxDynamicCast(FindWindowById(ID_CHO_PRESET),wxChoice);
        if(cmb)
        {
            cmb->Append(new_preset_name);
        }
    }
    return child;
}

bool PanelChorus::WriteToXML(wxXmlNode *node)
{
    if(node)
    {
        DataSave::NodeAttributesSetValue(node, attr_name_param_enable, param.enable ? "1" : "0");
        DataSave::NodeAttributesSetValue(node, attr_name_param_tone, mDoubleToString(param.tone).c_str(), true);
        DataSave::NodeAttributesSetValue(node, attr_name_param_pitch, mDoubleToString(param.pitch).c_str(), true);
        DataSave::NodeAttributesSetValue(node, attr_name_param_rate, mDoubleToString(param.rate).c_str(), true);
        DataSave::NodeAttributesSetValue(node, attr_name_param_wet, mDoubleToString(param.wet).c_str(), true);
        DataSave::NodeAttributesSetValue(node, attr_name_param_dry, mDoubleToString(param.dry).c_str(), true);
        return true;
    }
    return false;
}